perm filename MEMMF.TXT[MF,DEK] blob sn#762757 filedate 1984-07-27 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00007 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	On July 26--27, 1984 I made a version of MF that was designed to help spot
C00004 00003	I changed TRAP.MF by ending as follows: [if TRAP has changed, suitable
C00006 00004	@x special patches for memory allocation (follows "Eliminating addition/sub...")
C00008 00005	@x changes to dump/undump for the new memory stuff
C00009 00006	@x new debugging feature to write out a file of free locations (#11 0 16 0)
C00010 00007	% new stuff at the end of the very last page of the change file
C00011 ENDMK
C⊗;
On July 26--27, 1984 I made a version of MF that was designed to help spot
"memory wastage" errors.

(This was similar to what I did with TeX, see MEMTEX.TXT[tex,dek].)

Basically, the getavail and getnode routines were changed so that they
never recycled any nodes. Then the nodes that were not freed at the
end of the program were erroneous; and a second pass could be used to
identify the source of the erroneous nodes.

The following pages of this file show the additions I made to the
ordinary change file, in order to make MEMMF. Actually I made these
changes to BUGMF.CH; the mem_max was increased to 30000 and hi_mem_base
to 15000, besides the other changes cited.

(To create the FREE.TMP file, I used TeX's debugger, saying
#11 0 16 0
where 16 was a new option that writes that new file. When FREE.TMP
exists, INIMF (but not with a preloaded format) will load it.)
I changed TRAP.MF by ending as follows: [if TRAP has changed, suitable
modifications should be made]

@x
bye endtext
@y
endgroup endfor
fi fi fi; save <<,foo,bar,x,y,alpha,beta,s,q,e,/*\,\*/,w,pp,qq,//,!,p,inimf,',
 ↑,~,_aa__,**,***,++,texts,a,b,c,f,g,clear,dp,_,`','`,xx,yy;
errorstopmode; showstats; ddt;
@z

To run: First delete FREE.TMP.
Then run BUGMF and \input trap (as usual).
Then run BUGMF and &trap trap.mem.
When it stops with showstats, type D and then 11 0 16 0 -1 to the debugger.
Then run BUGMF and set breakpoints in get_avail and get_node;
\input trap  and/or &trap trap.mem will stop when unrecycled nodes
are first allocated.
@x special patches for memory allocation (follows "Eliminating addition/sub...")
get_avail←p;
@y
if not was_free[p] then
	begin @{@/
	'*************breakpoint*************';@/
	'***********for**debugging***********'@};
	end;
get_avail←p;
@z
@x
	begin link(#)←avail; avail←#;
@y
	begin link(#)←vail; vail←#;
@z
@x
get_node←r;
@y
if not was_free[r] then
	begin @{@/
	'*************breakpoint*************';@/
	'***********for**debugging***********'@};
	end;
get_node←r;
@z
@x
while is_empty(q) do @<Merge node |p| with node |q|@>;
@y
while false do @<Merge node |p| with node |q|@>;
@z
@x
p←avail; q←null; clobbered←false;
@y
p←vail; q←null; clobbered←false;
@z
@x changes to dump/undump for the new memory stuff
dump_int(mem_end); dump_int(avail);
for k←p to mem_end do dump_wd(mem[k]);
x←x+mem_end+1-p;
p←avail;
@y
dump_int(mem_end); dump_int(vail);
for k←p to mem_end do dump_wd(mem[k]);
x←x+mem_end+1-p;
p←vail;
@z
@x
undump(null)(mem_end)(avail);
@y
undump(null)(mem_end)(vail);
@z
@x new debugging feature to write out a file of free locations (#11 0 16 0)
15: panicking←not panicking;
@y
15: panicking←not panicking;
16: begin rewrite(free_file,'FREE.TMP');
	for k←0 to mem_max do
		begin free_file↑←free[k]; put(free_file);
		end;
	end;
@z
% new stuff at the end of the very last page of the change file
@ And still still more finally: Freed nodes go into |vail| instead of
|avail|, so there is no recycling.  An auxiliary |free_file| is used to
record memory usage.

@<Glob...@>=
@!vail:pointer;
@!free_file:file of boolean;

@ @<Set init...@>=
reset(free_file,'FREE.TMP','/O');
if not eof(free_file) then
	begin for k←0 to mem_max do
		begin was_free[k]←free_file↑; get(free_file);
		end;
	end;
@z